using System;
using System.Collections.Generic;
using Castle.Facilities.NHibernateIntegration;
using NHibernate;
using NHibernate.Criterion;

namespace OrderSystem.Core.Dao.Iml
{
    public class BaseDao<T> : IBaseDao<T>
    {
        private readonly Type persitentType = typeof (T);

        private readonly string sessionFactoryAlias;
        private readonly ISessionManager sessionManager;

        public BaseDao(ISessionManager sessionManager)
        {
            this.sessionManager = sessionManager;
        }

        public BaseDao(ISessionManager sessionManager, string sessionFactoryAlias) : this(sessionManager)
        {
            this.sessionFactoryAlias = sessionFactoryAlias;
        }

        #region IBaseDao<T> Members

        public virtual T GetById(int id)
        {
            using (ISession session = GetSession())
            {
                return session.Get<T>(id);
            }
        }

        public virtual List<T> GetAll()
        {
            return GetAll(null);
        }

        public virtual List<T> GetAll(IList<ICriterion> criterias)
        {
            using (ISession session = GetSession())
            {

                ICriteria criteria = session.CreateCriteria(persitentType);

                if (criterias != null)
                {
                    foreach (ICriterion criterium in criterias)
                    {
                        criteria.Add(criterium);
                    }
                }

                return criteria.List<T>() as List<T>;
            }
        }

        public virtual void Save(T instance)
        {
            using (ISession session = GetSession())
            {
                session.SaveOrUpdate(instance);
            }
        }

        public virtual void Delete(T instance)
        {
            using (ISession session = GetSession())
            {
                session.Delete(instance);
            }
        }

        #endregion

        private ISession GetSession()
        {
            return string.IsNullOrEmpty(sessionFactoryAlias) ? sessionManager.OpenSession() : sessionManager.OpenSession(sessionFactoryAlias);
        }
    }
}